package it.unina.lab.anm;

import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;

import loquendo.tts.engine.TTSConst;
import loquendo.tts.wrapper.LTTSWrapper;
import loquendo.tts.wrapper.LTTSWrapper.ErrorListener;
import loquendo.tts.wrapper.LTTSWrapper.InitListener;
import loquendo.tts.wrapper.LTTSWrapper.SpeechCompletedListener;
import android.util.Log;

public class TTS {

	private static TTS self;
	private LTTSWrapper myTts;
	private TTSState state = TTSState.UNINITIALIZED;
	private ArrayList<String> speechQueue;
	
	private enum TTSState {
		UNINITIALIZED, IDLE, SPEAKING, PAUSED
	}


	/** Called when the activity is first created. */
	private TTS() {
		Log.d("TTS: onCreate", "IN");
		initResFiles();
		myTts = new LTTSWrapper();
		myTts.init(ttsInitListener);
		myTts.setOnErrorListener(ttsErrorListener);
		//myTts.setOnSpeechCompletedListener(speechCompletedListener);
		speechQueue = new ArrayList<String>();
	}
	
	
	/** Singleton implementation **/
	public static TTS getTTS(){
		if(self == null)
			self = new TTS(); 
		
		return self;
	}

	/**
	 * Set up configuration files. _IMPORTANT_
	 */
	private void initResFiles() {
		Log.d("TTS: initResFiles", "IN");
		String packName = getClass().getPackage().getName();
		String dataDirStr = "/sdcard/LoquendoTTS/data";
		String licDirStr = "/sdcard/LoquendoTTS/"+packName;
		String[] defSessData = new String[6];

		File dataDir = new File(dataDirStr);
		if (dataDir.exists())
			defSessData[0] = "\"DataPath\" = \""+dataDirStr+"\"";
		else
			defSessData[0] = "\"DataPath\" = \"/LoquendoTTS/data\"";

		/*
		 * config file default.session must be put into
		 * the private application folder. License code file into the SD card 
		 */
		File defSessFile = new File("/data/data/" + packName
				+ "/default.session");

		defSessData[1] = "\"LibraryPath\" = \"/data/data/" + packName
				+ "/lib\"";
		defSessData[2] = "\"LicenseFile\" = \""+licDirStr+"/LicenseCode.txt\"";
		defSessData[3] = "\"LogFile\" = \"/sdcard/LoquendoTTS/error_log.txt\"";
		defSessData[4] = "\"TraceFile\" = \"\"";
		defSessData[5]="\"TextFormat\" = \"autodetect\"";

		File licDir = new File(licDirStr);
		File defSessDir = new File(defSessFile.getParent());
		try {
			licDir.mkdir();
			defSessDir.mkdir();
			if (!defSessFile.createNewFile()) {
				defSessFile.delete();
				defSessFile.createNewFile(); // create from scratch
			}
			PrintWriter pw = new PrintWriter(defSessFile);
			for (int i = 0; i < defSessData.length; i++) {
				pw.println(defSessData[i]);
			}
			pw.close();

		} catch (IOException e) {
			e.printStackTrace();
		} catch (SecurityException se) {
			se.printStackTrace();
		}

	}
	
	private InitListener ttsInitListener = new InitListener() {
		public void onInit(int version) {
			Log.d("TTS: TTS.InitListener.onInit", "state=" + state);

			if (state == TTSState.UNINITIALIZED) {
				myTts.setParam("TextEncoding", "utf-8");
				myTts.enableEvent(TTSConst.TTSEVT_BOOKMARK, true);
				myTts.setVoice("Paola");
				myTts.setLanguage("it");
				state = TTSState.IDLE;
				
			} 
		}
	};

	private ErrorListener ttsErrorListener = new ErrorListener() {
		public void onError(String msg) {
			Log.d("LTTSDemo.ErrorListener", msg);
			if (msg.contains("Voice") || msg.contains("Language")) {
				new RuntimeException("Errore carincamento voci o inizializzazione!");
			} else {
				state = TTSState.IDLE;
			}
		}
	};


	/* private SpeechCompletedListener speechCompletedListener = new SpeechCompletedListener() {
		public void onSpeechCompleted() {
			Log.d("LTTSDemo.SpeechCompletedListener", "IN");
			state = TTSState.IDLE;
		}
	}; */

	
	
	
	public void setSpeechCompletedListener(SpeechCompletedListener sl){
		myTts.setOnSpeechCompletedListener(sl);
	}


	public void speak(String text_tts) {
		Log.d("LTTSDemo.speak", "speaking: " + text_tts);
		if (myTts != null && myTts.isSpeaking()) {
			myTts.stop();
			speechQueue.clear();
			speechQueue.add(text_tts);
		} else {
			myTts.speak(text_tts);
			Log.d("LTTSDemo.speak", "3- isSpeaking=" + myTts.isSpeaking());
		}

	}
	
	
	
	public void stopSpeak(){
		Log.d("LTTSDemo.stopSpeak", "Stop speaking!");
		if (myTts != null && myTts.isSpeaking())
			myTts.stop();
	}
}
